package com.ruicar.afs.cloud.afscase.manuallabel.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.afscase.approvemakelabel.entity.ApproveMakeLabel;
import com.ruicar.afs.cloud.afscase.approvemakelabel.entity.LoanLabelInfo;
import com.ruicar.afs.cloud.afscase.approvemakelabel.service.ApproveMakeLabelService;
import com.ruicar.afs.cloud.afscase.approvemakelabel.service.LoanLabelInfoService;
import com.ruicar.afs.cloud.afscase.autoaudit.service.IRuleAtomDataService;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelBaseInfo;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelRiskInfo;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelAffiliatedUnitsService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelBaseInfoService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelRiskInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.*;
import com.ruicar.afs.cloud.afscase.infomanagement.service.*;
import com.ruicar.afs.cloud.afscase.manuallabel.entity.ManualLabel;
import com.ruicar.afs.cloud.afscase.manuallabel.mapper.ManualLabelMapper;
import com.ruicar.afs.cloud.afscase.manuallabel.service.ManualLabelService;
import com.ruicar.afs.cloud.afscase.risk.entity.CaseTortoiseApply;
import com.ruicar.afs.cloud.afscase.risk.service.CaseTortoiseApplyService;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.rules.service.AfsRuleInfoService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import com.ruicar.afs.cloud.common.rules.RuleHelper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;


/**
 * @author jiaqi.guo
 * @version 1.0
 * @created 2020/5/19 11:40
 */
@Service
@AllArgsConstructor
@Data
@Slf4j
public class ManualLabelServiceImpl extends ServiceImpl<ManualLabelMapper, ManualLabel> implements ManualLabelService {

    private AfsRuleInfoService afsRuleInfoService;

    private ApproveMakeLabelService approveMakeLabelService;

    private LoanLabelInfoService loanLabelInfoService;

    private CaseBaseInfoService caseBaseInfoService;

    private CaseCarInfoService caseCarInfoService;

    private CaseCostInfoService caseCostInfoService;

    private ChannelRiskInfoService channelRiskInfoService;

    private ChannelAffiliatedUnitsService channelAffiliatedUnitsService;

    private CaseChannelInfoService caseChannelInfoService;

    private CaseCarStyleDetailService carStyleDetailInfoService;

    private ChannelBaseInfoService channelBaseInfoService;

    private CaseContractInfoService caseContractInfoService;

    private IRuleAtomDataService ruleAtomDataService;

    private CaseTortoiseApplyService caseTortoiseApplyService;


    /**
     * @description: 根据ID获取标签信息
     * @author jiaqi.guo
     * @created 2020/6/4 11:17
     * @version 1.0
     */
    @Override
    public ManualLabel queryAllLabelListById(Long id) {
        return getById(id);
    }

    /**
     * @description: 案件命中规则自动维护
     * @author jiaqi.guo
     * @created 2020/6/4 11:18
     * @version 1.0
     */
    public void transmitDataForLabel(String applyNo) {

        JSONObject params = new JSONObject();

        CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
                .eq(CaseBaseInfo::getApplyNo, applyNo));
        log.info("------------------自动标签规则属性组装 Start --------------------");
        if (ObjectUtils.isNotEmpty(caseBaseInfo)) {
            /**业务类型*/
            String businessType = caseBaseInfo.getBusinessType();
            params.put("businessType", businessType);

            /**车辆类型*/
            String carType = caseBaseInfo.getCarType();
            params.put("carType", carType);

            /**车辆属性*/
            String carNature = caseBaseInfo.getCarNature();
            params.put("carNature", carNature);

            /**运营方式*/
            String operateWay = caseBaseInfo.getOperateWay();
            params.put("operateWay", operateWay);

            /**挂靠方式*/
            String affiliatedWay = caseBaseInfo.getAffiliatedWay();
            params.put("affiliatedWay", affiliatedWay);

            /**金融产品*/
            Long productId = caseBaseInfo.getProductId();
            params.put("productId", Convert.toStr(productId, ""));

            /**自动标识*/
            String automaticTag = caseBaseInfo.getAutomaticTag();
            params.put("automaticTag", Convert.toStr(automaticTag, ""));
        }
        CaseChannelInfo caseChannelInfo = caseChannelInfoService.getOne(Wrappers.<CaseChannelInfo>query().lambda()
                .eq(CaseChannelInfo::getApplyNo, applyNo));
        if (ObjectUtils.isNotEmpty(caseChannelInfo)) {
            /**经销商名称*/
            String dealerName = caseChannelInfo.getDealerName();
            params.put("dealerName", dealerName);
            /**---------------------------------   渠道风控信息    --------------------------------**/
            ChannelBaseInfo channelBaseInfo = channelBaseInfoService.getOne(Wrappers.<ChannelBaseInfo>query().lambda()
                    .eq(ChannelBaseInfo::getChannelCode, caseChannelInfo.getDealerNo()));
            if (ObjectUtils.isNotEmpty(channelBaseInfo)) {
                ChannelRiskInfo channelRiskInfo = channelRiskInfoService.getOne(Wrappers.<ChannelRiskInfo>query().lambda()
                        .eq(StringUtils.isNotBlank(caseChannelInfo.getDealerNo()), ChannelRiskInfo::getChannelId, channelBaseInfo.getChannelId())
                        .eq(StringUtils.isNotBlank(channelBaseInfo.getBusinessType()), ChannelRiskInfo::getBusinessType, channelBaseInfo.getBusinessType()));
                if (ObjectUtils.isNotEmpty(channelRiskInfo)) {
                    /**优质登记*/
                    String qualityGrade = channelRiskInfo.getQualityGrade();
                    params.put("qualityGrade", qualityGrade);
                }
            }
        }
        /**---------------------------------     车辆信息     ----------------------------------**/
        CaseCarInfo caseCarInfo = caseCarInfoService.getOne(Wrappers.<CaseCarInfo>query().lambda()
                .eq(CaseCarInfo::getApplyNo, applyNo));
        if (ObjectUtils.isNotEmpty(caseCarInfo)) {
            /**车辆级别*/
            String carBodyClass = caseCarInfo.getCarBodyClass();
            params.put("carBodyClass", carBodyClass);

            /**车型*/
            String modelCode = caseCarInfo.getModelCode();
            params.put("modelCode", modelCode);
        }
        /**---------------------------------     车辆详情     ----------------------------------**/
        List<CaseCarStyleDetail> cartyleDetailInfo = carStyleDetailInfoService.list(Wrappers.<CaseCarStyleDetail>query().lambda()
                .eq(CaseCarStyleDetail::getCarId, caseCarInfo.getId()));

        if (ObjectUtils.isNotEmpty(cartyleDetailInfo) && cartyleDetailInfo.size() > 0) {
            /**是否新能源*/
            String isGreen = cartyleDetailInfo.get(0).getIsGreen();
            params.put("isGreen",isGreen);

            /** 资产主类*/
            String assetsClass = cartyleDetailInfo.get(0).getCarType();
            params.put("carTypeMain", assetsClass);

            /** 资产子类*/
            String carTypeDetail = cartyleDetailInfo.get(0).getCarTypeDetail();
            params.put("carTypeDetail", carTypeDetail);
        }
        BigDecimal contAmt = BigDecimal.ZERO;
        BigDecimal tailPayAmt = BigDecimal.ZERO;
        BigDecimal subsidyTotalAmt = BigDecimal.ZERO;

        /**  车款融资信息 车款 **/
        FinCostDetails carAmtCostInfoCar = caseCostInfoService.getOne(Wrappers.<FinCostDetails>query().lambda()
                .eq(FinCostDetails::getApplyNo, applyNo)
                .eq(FinCostDetails::getCostType, CostTypeEnum.CARAMT.getCode())
        );

        /**  车款融资信息 附件贷 **/
        FinCostDetails carAmtCostInfoAdd = caseCostInfoService.getOne(Wrappers.<FinCostDetails>query().lambda()
                .eq(FinCostDetails::getApplyNo, applyNo)
                .eq(FinCostDetails::getCostType, CostTypeEnum.AFFIXAMT.getCode())
        );
        if (ObjectUtils.isNotEmpty(carAmtCostInfoAdd)) {
            /** 附加贷金额*/
            BigDecimal loanAmt = carAmtCostInfoAdd.getLoanAmt();
            params.put("appendAmount", loanAmt);
            contAmt = contAmt.add(Convert.toBigDecimal(loanAmt, BigDecimal.ZERO));
            tailPayAmt = contAmt.add(Convert.toBigDecimal(carAmtCostInfoAdd.getDiscountAmt(), BigDecimal.ZERO));
            subsidyTotalAmt = contAmt.add(Convert.toBigDecimal(carAmtCostInfoAdd.getDiscountAmt(), BigDecimal.ZERO));


        }
        if (ObjectUtils.isNotEmpty(carAmtCostInfoCar)) {

            /**首付比例*/
            params.put("downPayScale", carAmtCostInfoCar.getDownPayScale().divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP));

            /**还款方式*/
            String repayMode = carAmtCostInfoCar.getAlgorithmType();
            params.put("repayMode", repayMode);

            contAmt = contAmt.add(Convert.toBigDecimal(carAmtCostInfoCar.getLoanAmt(), BigDecimal.ZERO));
            tailPayAmt = contAmt.add(Convert.toBigDecimal(carAmtCostInfoCar.getDiscountAmt(), BigDecimal.ZERO));
            subsidyTotalAmt = contAmt.add(Convert.toBigDecimal(carAmtCostInfoCar.getDiscountAmt(), BigDecimal.ZERO));

        }

        /**贷款金额*/
        params.put("loanAmount", contAmt);

        /**贴息金额*/
        params.put("tailPayAmt", tailPayAmt);

        /**尾款金额*/
        params.put("subsidyTotalAmt", subsidyTotalAmt);

        ChannelBaseInfo channelInfo = channelBaseInfoService.getOne(Wrappers.<ChannelBaseInfo>query().lambda()
                .eq(ChannelBaseInfo::getChannelCode, caseChannelInfo.getDealerNo())
        );
        /**---------------------------------   渠道风控信息    --------------------------------**/
        if (ObjectUtils.isNotEmpty(channelInfo)) {
            ChannelRiskInfo channelRiskInfo = channelRiskInfoService.getOne(Wrappers.<ChannelRiskInfo>query().lambda()
                    .eq(ChannelRiskInfo::getChannelId, channelInfo.getChannelId())
                    .eq(ChannelRiskInfo::getBusinessType, caseBaseInfo.getBusinessType()));

            if (ObjectUtils.isNotEmpty(channelRiskInfo)) {
                /**优质等级*/
                String qualityGrade = channelRiskInfo.getQualityGrade();
                params.put("qualityGrade", qualityGrade);
                /**合作商评级*/
                params.put("channelGrade", channelRiskInfo.getChannelGrade());
            }
            /**经销商省份*/
            params.put("channelProvince", channelInfo.getChannelProvince());
            /**经销商城市*/
            params.put("channelCity", channelInfo.getChannelCity());
            /**渠道归属*/
            if (ObjectUtils.isNotEmpty(channelInfo)) {
                params.put("channelBelong", channelInfo.getChannelBelong());
            }
        }
        log.info("------------------自动标签规则属性组装 End --------------------");
        /**----------TODO GJQ ------*/
        /** 角色+小程序进件*/

        // 玄武最新返回数据
        CaseTortoiseApply tortoiseApply = caseTortoiseApplyService.list(
                Wrappers.<CaseTortoiseApply>lambdaQuery()
                    .eq(CaseTortoiseApply::getApplyNo,applyNo)
                    .isNotNull(CaseTortoiseApply::getNoticeDate)
                    .orderByDesc(CaseTortoiseApply::getNoticeDate)
        ).stream().findFirst().orElse(new CaseTortoiseApply());

        /**反欺诈评分*/
        params.put("antiFraudGrade", Convert.toInt(tortoiseApply.getFraudResultScore(),-1));
        /**决策引擎评分*/
        params.put("decisionGrade", Convert.toInt(tortoiseApply.getScore(),-1));

        // 获取所有标签库信息(生效，自动、对内)
        List<ManualLabel> manualLabelList = this.list(Wrappers.<ManualLabel>query().lambda()
                .eq(ManualLabel::getStatus, LabelStatusEnum.TAKE_EFFECT.getCode())
                .eq(ManualLabel::getLabel, LabelWayEnum.AUTOMATIC.getCode())
                .eq(ManualLabel::getLabelPhase, LabelPhaseEnum.CREDITADUIT.getCode())
                .isNotNull(ManualLabel::getRuleId)
        );
        //删除已命中标签 考虑信审退回重审
        approveMakeLabelService.remove(Wrappers.<ApproveMakeLabel>query().lambda()
                .eq(ApproveMakeLabel::getApplyNo, applyNo)
                .ne(ApproveMakeLabel::getLabelClassification, AfsEnumUtil.key(LabelClassEnum.TORTOISE)));
        //命中规则之后返回相应的标签 保存list
        for (ManualLabel label : manualLabelList) {
            boolean RuleRunResult;
            try {
                RuleRunResult = RuleHelper.runRule(params, label.getId().toString()).getHit();
            } catch (Exception e) {
                RuleRunResult = false;
                log.info("调用规则失败异常原因：{}", e.getMessage());
            }
            if (RuleRunResult) {
                log.info("------------------自动标签规则已命中编号:" + label.getId().toString() + "--------------------");
                ApproveMakeLabel approveMakeLabel = new ApproveMakeLabel();
                ManualLabel manualLabel = this.queryAllLabelListById(label.getId());
                approveMakeLabel.setApplyNo(applyNo);
                approveMakeLabel.setLabelId(manualLabel.getId());
                approveMakeLabel.setLabelName(manualLabel.getLabelName());
                approveMakeLabel.setLabelPhase(manualLabel.getLabelPhase());
                approveMakeLabel.setLabelColor(manualLabel.getLabelColor());
                approveMakeLabel.setLabelType(manualLabel.getLabelType());
                approveMakeLabel.setLabelLocation(manualLabel.getLabelLocation());
                approveMakeLabel.setLabelSort(manualLabel.getLabelSort());
                approveMakeLabel.setLabelPattern(manualLabel.getLabel());
                approveMakeLabel.setLabelClassification(manualLabel.getLabelClassification());
                approveMakeLabelService.save(approveMakeLabel);
                //处理原因:涉及到自动标签、手动标签共同查询
                String labelIdRepeat = caseBaseInfo.getLabelIdRepeat();
                String[] oldStr = null;
                if (StringUtils.isNotBlank(labelIdRepeat)) {
                    oldStr = labelIdRepeat.split(",");
                }
                String newStr = "";
                if (oldStr != null && oldStr.length > 0) {
                    for (int i = 0; i < oldStr.length; i++) {
                        newStr += oldStr[i] + ",";
                    }

                }
                newStr += manualLabel.getId() + ",";
                caseBaseInfo.setLabelIdRepeat(newStr);
                caseBaseInfoService.updateById(caseBaseInfo);

            }
        }
    }

    //规则命中维护放款标签信息
    public void loanForLabel(String contractNo) {
        JSONObject params = ruleAtomDataService.getCommonAtomRunParamsLoan(contractNo);
        CaseContractInfo caseContractInfo= caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query()
                .lambda().eq(CaseContractInfo::getContractNo,contractNo));
        String applyNo=caseContractInfo.getApplyNo();
        // 获取所有标签库信息(生效，自动、对内)
        List<ManualLabel> manualLabelList = this.list(Wrappers.<ManualLabel>query().lambda()
                .eq(ManualLabel::getStatus, LabelStatusEnum.TAKE_EFFECT.getCode())
                .eq(ManualLabel::getLabel, LabelWayEnum.AUTOMATIC.getCode())
                .eq(ManualLabel::getLabelPhase, LabelPhaseEnum.LOANS.getCode())
                .isNotNull(ManualLabel::getRuleId)
        );
        //删除已命中标签退回重新提交
        loanLabelInfoService.remove(Wrappers.<LoanLabelInfo>query().lambda()
                .eq(LoanLabelInfo::getApplyNo, applyNo)
                .eq(LoanLabelInfo::getContractNo, contractNo));
        //命中规则之后返回相应的标签 保存list
        for (ManualLabel label : manualLabelList) {
            boolean RuleRunResult;
            try {
                RuleRunResult = RuleHelper.runRule(params, label.getId().toString()).getHit();
            } catch (Exception e) {
                RuleRunResult = false;
                log.info("调用规则失败异常原因：{}", e.getMessage());
            }
            if (RuleRunResult) {
                log.info("------------------自动标签规则已命中编号:" + label.getId().toString() + "--------------------");
                LoanLabelInfo loanLabelInfo = new LoanLabelInfo();
                ManualLabel manualLabel = this.queryAllLabelListById(label.getId());
                loanLabelInfo.setApplyNo(applyNo);
                loanLabelInfo.setContractNo(contractNo);
                loanLabelInfo.setLabelId(manualLabel.getId());
                loanLabelInfo.setLabelName(manualLabel.getLabelName());
                loanLabelInfo.setLabelPhase(manualLabel.getLabelPhase());
                loanLabelInfo.setLabelColor(manualLabel.getLabelColor());
                loanLabelInfo.setLabelType(manualLabel.getLabelType());
                loanLabelInfo.setLabelLocation(manualLabel.getLabelLocation());
                loanLabelInfo.setLabelSort(manualLabel.getLabelSort());
                loanLabelInfo.setLabelPattern(manualLabel.getLabel());
                loanLabelInfo.setLabelClassification(manualLabel.getLabelClassification());
                loanLabelInfo.setIsArchive(manualLabel.getIsArchive());
                loanLabelInfoService.save(loanLabelInfo);
                //处理原因:涉及到自动标签、手动标签共同查询
                String labelIdRepeat = caseContractInfo.getLabelIdRepeat();
                String[] oldStr = null;
                if (StringUtils.isNotBlank(labelIdRepeat)) {
                    oldStr = labelIdRepeat.split(",");
                }
                String newStr = "";
                if (oldStr != null && oldStr.length > 0) {
                    for (int i = 0; i < oldStr.length; i++) {
                        newStr += oldStr[i] + ",";
                    }
                }
                newStr += manualLabel.getId() + ",";
                caseContractInfo.setLabelIdRepeat(newStr);
                caseContractInfoService.updateById(caseContractInfo);
            }
        }
    }
}
